#ifndef BUFFERMANAGER_H
#define BUFFERMANAGER_H

#include "BufferFrame.h"
#include <map>
#include <iostream>
#include <queue>
#include "Semaphore.h"
#include "GlobalStuff.h"

using namespace std;

class BufferManager
{
public:
    void unfixPage(BufferFrame& frame, bool isDirty);
    virtual BufferFrame& getPage(unsigned pageId, bool exclusive);
    virtual ~BufferManager();

    BufferManager(const BufferManager& other) = delete;
    BufferManager operator=(const BufferManager& other) = delete;

    int getBufferHits();
    int getBufferMisses();

protected:
    BufferManager(const std::string& filename, unsigned size);

    FILE* file;
    unsigned bufferSize;
    BufferFrame** frames;
    map<unsigned, int> index;
    queue<unsigned> frameQueue;
    queue<unsigned> freeQueue;

    SEMAPHORE indexSemaphore;
    SEMAPHORE frameQueueSemaphore;
    SEMAPHORE fileSystemLock;
    SEMAPHORE hitSemaphore;
    SEMAPHORE* arrayLocks;

    int getIndex(unsigned pageId);
    virtual int swapPage();
    virtual void writeToDisk(BufferFrame& frame);
    BufferFrame* loadPage(unsigned pageId);

    // HIT & MISSES counter
    int bufferHits;
    int bufferMisses;

private:
};

#endif // BUFFERMANAGER_H
